/**
空对象模式（Null Object Pattern）

一个空对象取代 NULL 对象实例的检查。
Null 对象不是检查空值，而是反应一个不做任何动作的关系。
这样的 Null 对象也可以在数据不可用的时候提供默认的行为。
在空对象模式中，我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类，还创建一个未对该类做任何实现的空对象类，该空对象类将无缝地使用在需要检查空值的地方。
*/
main(List<String> args) {
  AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
  AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
  AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
  AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");

  print("Customers");
  print(customer1.getName());
  print(customer2.getName());
  print(customer3.getName());
  print(customer4.getName());
}

//////////////////////////////////////////////////////////////////

///
/// 创建一个抽象类
///
abstract class AbstractCustomer {
  String _name;
  bool isNil();
  String getName();
}

///
/// 创建扩展了上述类的实体类
///
class RealCustomer extends AbstractCustomer {
  RealCustomer(String name) {
    this._name = name;
  }

  @override
  String getName() {
    return _name;
  }

  @override
  bool isNil() {
    return false;
  }
}

class NullCustomer extends AbstractCustomer {
  @override
  String getName() {
    return "Not Available in Customer Database";
  }

  @override
  bool isNil() {
    return true;
  }
}

///
/// 创建 CustomerFactory 类
///
class CustomerFactory {
  static final List<String> _names = ["Rob", "Joe", "Julie"];

  static AbstractCustomer getCustomer(String name) {
    for (int i = 0; i < _names.length; i++) {
      if (_names[i] == name) {
        return new RealCustomer(name);
      }
    }
    return new NullCustomer();
  }
}
